package com.ktgj.common.core.utils.helper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;


public class CloneHelper
{
	private final static Logger LOGGER = LoggerFactory.getLogger(CloneHelper.class);

	public static <T> T deepClone(Object o)
	{
		try
		{
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			ObjectOutputStream stream = new ObjectOutputStream(os);
			stream.writeObject(o);
			stream.close();

			ByteArrayInputStream bis = new ByteArrayInputStream(os.toByteArray());
			ObjectInputStream oStream = new ObjectInputStream(bis);
			@SuppressWarnings("unchecked")
			T t = (T) oStream.readObject();
			return t;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			LOGGER.error(e.getMessage());
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	public static <T> T propertyClone(T o)
	{
		T result = null;
		Class<?> clazz = o.getClass();
		try
		{
			result = (T) clazz.newInstance();
		}
		catch (Exception e)
		{
			LOGGER.error(e.getMessage());
			return null;
		}

		for (Field field : clazz.getDeclaredFields())
		{
			boolean access = field.isAccessible();
			try
			{
				Object val = field.get(o);
				if (!access) field.setAccessible(true);
				field.set(result, val);

			}
			catch (Exception e)
			{
				LOGGER.error(e.getMessage());
			}
			finally
			{
				if (!access) field.setAccessible(false);
			}
		}

		return result;
	}
}
